next up previous
Next: 6.2 The D11 Interface Up: 6 Implementing D11 Previous: 6 Implementing D11

6.1 Within the D11 Active Context

The D11 window system kernel is implemented as an active context and bootstrapped as described in the previous section. The executable code for the D11 kernel can be largely reused from the X11 server's implementation. Code that needs to be reimplemented for D11 includes initialization, the main event loop, and client I/O code. The vast bulk of the X server code such as machine-independent and device-dependent rendering code, font handling code, etc. can be identical to the X11 server's implementation.

Once the active context creator ``populates'' and activates the active context, it takes the role of a housekeeper for the active context. It manages window system kernel tasks that are not initiated by D11 program requests. For example, reading input events, handling the screen saver, managing window system reset, and reaping terminated APPs are all done by the D11 kernel housekeeping thread.

D11 programs attach to the D11 active context during XOpenDisplay. The first ``establish connection'' protected procedure call enters the D11 kernel and establishes the data structures for the new D11 connection. Within the D11 active context is a global locking semaphore that is acquired whenever a process running within the active context manipulates global data structures. Acquiring this semaphore while executing requests satisfies the X atomicity requirement. While a global lock may seem too coarse, the request dispatch loop of current single-threaded X servers is logically equivalent to a global lock.

Once a connection is established, the D11 program can make protected procedure calls. Based on the op parameter to the entry_func, the D11 kernel executes the correct code to handle the D11 request. When executing a request, the APP may directly manipulate the caller's address space to read arguments and return data (such accesses must be correctly protected against memory violations).

Because multiple processes may run in the active context at one time, code within the D11 active context must correctly lock accesses to data structures. Because of the use of a single global lock, most locking concerns are straightforward. Existing X server code for executing requests can generally assume the global lock is already acquired and so existing code does not need any special locking. Inexpensive locking around the global memory allocation pool is necessary. Multi-threaded and multi-rendering X servers [16,25] already abide by this requirement.

So a typical D11 request is executed by generating a protected procedure call that enters the D11 active context, acquires the global lock, calls the appropriate request execution code, releases the lock, and returns from the protected procedure call. In the process of executing a request, data may be transferred from the caller's memory space; and if the request returns a reply, data may be written into the caller's memory space.

As mentioned earlier, the D11 active context creator is watching for asynchronous events such as mouse or keyboard input. When such input arrives, the housekeeping process will acquire the global lock, determine how to handle the input, generate events to be sent to D11 connections if necessary, and release the global lock. Generating events for a D11 connection is done by placing events in the connection's pending event queue. Each queue has a lock that arbitrates access to the queue. Any D11 active context process can send events by acquiring the lock for a D11 connection's event queue, appending the events to the queue, and calling acnotify for the APP owning the queue, then releasing the queue lock. Errors are also placed in the queue. But replies are returned synchronously.



next up previous
Next: 6.2 The D11 Interface Up: 6 Implementing D11 Previous: 6 Implementing D11



Mark Kilgard
Sun Jan 7 19:06:56 PST 1996